package com.jkgh.remedium.tools {
	
	import com.jkgh.remedium.RemediumSystem;
	import com.jkgh.remedium.objects.messages.RemediumOutMessage;
	import com.jkgh.remedium.states.GatheringState;
		
	public class RemediumTools {
	
		public static function produceString(remedium:RemediumSystem, s:String):void {
			if (s == null) {
				remedium.consumeInt(-1);
			} else {
				var length:int = s.length;
				remedium.consumeInt(length);
				for (var i:int = 0; i<length; ++i) {
					remedium.consumeByte(s.charCodeAt(i));
				}
			}
		}
	
		public static function consumeString(remedium:RemediumSystem, future:Function):void {
			remedium.setState(new GatheringState(4, function(remedium:RemediumSystem):void {
				
				var length:int = remedium.produceInt();
				if (length > 0) {
					remedium.setState(new GatheringState(length, function(remedium:RemediumSystem):void {
						
						var ret:String = "";
						for (var i:int = 0; i<length; ++i) {
							ret += String.fromCharCode(remedium.produceByte());
						}
						
						future(ret);
						
					}));
				} else if (length == 0) {
					future("");
				} else {
					future(null);
				}
	
			}));
		}
	
		public static function consumeInt(remedium:RemediumSystem, future:Function):void {
			remedium.setState(new GatheringState(4, function(remedium:RemediumSystem):void {
				
				var ret:int = remedium.produceInt();
				future(ret);
				
			}));
		}
	
		public static function produceIntArray(remedium:RemediumSystem, ints:Vector.<int>):void {
			if (ints == null) {
				remedium.consumeInt(-1);
			} else {
				var length:int = ints.length;
				remedium.consumeInt(length);
				for each (var i:int in ints) {
					remedium.consumeInt(i);
				}
			}
		}
		
		public static function produceStringArray(remedium:RemediumSystem, ss:Vector.<String>):void {
			if (ss == null) {
				remedium.consumeInt(-1);
			} else {
				var length:int = ss.length;
				remedium.consumeInt(length);
				for each (var s:String in ss) {
					produceString(remedium, s);
				}
			}
		}
		
		public static function consumeIntArray(remedium:RemediumSystem, future:Function):void {
			remedium.setState(new GatheringState(4, function(remedium:RemediumSystem):void {
				
				var length:int = remedium.produceInt();
				if (length > 0) {
					remedium.setState(new GatheringState(4*length, function(remedium:RemediumSystem):void {
						
						var ret:Vector.<int> = new Vector.<int>();
						for (var i:int = 0; i<length; ++i) {
							ret.push(remedium.produceInt());;
						}
						
						future(ret);
						
					}));
				} else if (length == 0) {
					future(new Vector.<int>());
				} else {
					future(null);
				}
				
			}));
		}
		
		public static function consumeStringArray(remedium:RemediumSystem, future:Function):void {
			remedium.setState(new GatheringState(4, function(remedium:RemediumSystem):void {
				
				var length:int = remedium.produceInt();
				if (length == -1) {
					future(null);
				} else if (length == 0) {
					future(new Vector.<String>());
				} else {
					var i:int = 0;
					var result:Vector.<String> = new Vector.<String>(length, true);
					var onO:Function = function(o:String):void {
						result[i++] = o;
						if (i == length) {
							future(result);
						} else {
							consumeString(remedium, onO);
						}
					};
					consumeString(remedium, onO);
				}
			}));
		}
		
		public static function produceObjectArray(remedium:RemediumSystem, message:RemediumOutMessage, objects:*):void {
			if (objects == null) {
				remedium.consumeInt(-1);
			} else {
				var length:int = objects.length;
				remedium.consumeInt(length);
				for (var i:int = 0; i<length; ++i) {
					message.produceObject(objects[i], remedium);
				}
			}
		}
	}
}